package com.glitter.player.springbootinfluxdb.connect;

import lombok.Data;
import org.influxdb.InfluxDB;

import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.Point;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**InfluxDB 连接
 * @program:
 * @author: Player
 * @create: 2019-09-04
 **/
@Data
public class InfluxDBConnect {
    /*用户名*/
    private String username;
    /*密码*/
    private String password;
    /*连接地址*/
    private String url;
    /*数据库名*/
    private String databaseName;

    /*连接*/
    private InfluxDB influxDB;

    /*保存策略*/
    private String retentionPolicy;



    public InfluxDBConnect(String username, String password, String url, String databaseName) {
        this.username = username;
        this.password = password;
        this.url = url;
        this.databaseName = databaseName;
        initConnect();
    }

    private void initConnect(){
        if(influxDB==null){
            this.influxDB = InfluxDBFactory.connect(url, username, password);
            createTable("test");
        }
    }


    private void createTable(String tableName){
        Query query=new Query("create database \""+tableName+"\"",this.databaseName,true);
        influxDB.query(query);
    }

    public Map<String, List<Object>> showDatabasesList(){
        Query query=new Query("show databases",this.databaseName);
        QueryResult queryResult = influxDB.query(query);
        return transformationResultQuery(queryResult);
    }

    /*tags是带索引的,fields是不带索引的*/
    public void insert(String tableName, Map<String,String> tags, Map<String, Object> fields, long time, TimeUnit timeUnit){
        Point.Builder builder = Point.measurement(tableName);
        builder.tag(tags);
        builder.fields(fields);
        if (0 != time) {
            builder.time(time, timeUnit);
        }
        influxDB.write(this.databaseName,retentionPolicy, builder.build());
    }

    /*查询*/
    public Map<String, List<Object>> query (String sql){
        Query query = new Query(sql, this.databaseName);
        QueryResult queryResult = influxDB.query(query);
        return transformationResultQuery(queryResult);
    }




    /*
    * policyName策略名
    * duration：保存天数
    * replication:保存份数
    * isDefault：是否默认
    * */
    public void createRetentionPolicy(String policyName, String duration, int replication, Boolean isDefault) {
        String sql = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s ", policyName,
                this.databaseName, duration, replication);
        if (isDefault) {
            sql = sql + " DEFAULT";
            //this.retentionPolicy=policyName;
        }
        this.query(sql);
    }



    private Map <String,List<Object>> transformationResultQuery(QueryResult queryResult){
        if(queryResult.getResults().get(0).getSeries()==null)
            return null;
        Map <String,List<Object>> columnValueMap=new HashMap<>();
        queryResult.getResults().forEach(result -> result.getSeries().forEach(series -> {
            series.getValues().forEach(value->{
                for (int i = 0; i <value.size() ; i++) {
                    List<Object> valueList = columnValueMap.get(series.getColumns().get(i));
                    if (valueList==null){
                        valueList=new ArrayList<>();
                    }
                    valueList.add(value.get(i));
                    columnValueMap.put(series.getColumns().get(i),valueList);
                }
            });
        }));
        return columnValueMap;
    }



}
